package com.ht.impl.shape;

import com.mxgraph.canvas.mxGraphics2DCanvas;
import com.mxgraph.model.mxCell;
import com.mxgraph.shape.mxBasicShape;
import com.mxgraph.shape.mxIShape;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxStylesheet;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class htShapeArray extends mxBasicShape {

    public void paintShape(mxGraphics2DCanvas canvas, mxCellState state) {
        Map<String, Object> style = state.getStyle();
        Rectangle2D unionRec = null;
        int cellSize = Integer.parseInt(style.get("arraySize").toString());
        Map<String, Object>[] sty = new Map[cellSize];
        Rectangle2D[] rects = new Rectangle2D[cellSize];
        for (int i = 0; i < cellSize; i++) {
            sty[i] = new HashMap<String, Object>();
            String s = (String) style.get("cellInfo" + i);
            s = s.replace("&", ";");
            s = s.replace(":", "=");
            mxStylesheet stylesheet = state.getView().getGraph().getStylesheet();
            if (s.contains("isVertex=false")) {
                sty[i].putAll(stylesheet.getCellStyle(s, stylesheet.getDefaultEdgeStyle()));
            } else
                sty[i].putAll(stylesheet.getCellStyle(s, stylesheet.getDefaultVertexStyle()));
            for (String key : style.keySet()) {
                if (!key.startsWith("cellInfo") && !key.equals("shape"))
                    sty[i].put(key, style.get(key));
            }
            double x = Double.parseDouble(sty[i].get("x").toString());
            double y = Double.parseDouble(sty[i].get("y").toString());
            double w = Double.parseDouble(sty[i].get("w").toString());
            double h = Double.parseDouble(sty[i].get("h").toString());
            rects[i] = new Rectangle2D.Double(x, y, w, h);
            if (unionRec == null) {
                unionRec = new Rectangle2D.Double(x, y, w, h);
            } else
                unionRec.add(rects[i]);
        }
        if (unionRec == null)
            unionRec = new Rectangle2D.Double(0, 0, 100, 100);
        double sx = state.getWidth() / unionRec.getWidth();
        double sy = state.getHeight() / unionRec.getHeight();
        AffineTransform transform = AffineTransform.getScaleInstance(sx, sy);
        Point2D.Double temp = new Point2D.Double();
        transform.transform(new Point2D.Double(unionRec.getX(), unionRec.getY()), temp);
        double dx = state.getX() - temp.getX();
        double dy = state.getY() - temp.getY();
        for (int i = 0; i < cellSize; i++) {
            mxCellState clonedState;
            if (sty[i].containsKey("isVertex") && sty[i].get("isVertex").equals("true")) {
                Point2D destP = new Point2D.Double();
                transform.transform(new Point2D.Double(rects[i].getX(), rects[i].getY()), destP);
                mxRectangle mxRec = new mxRectangle(destP.getX() + dx, destP.getY() + dy, rects[i].getWidth() * sx, rects[i].getHeight() * sy);
                clonedState = (mxCellState) state.clone();
                clonedState.setBoundingBox(mxRec);
                clonedState.setX(mxRec.getX());
                clonedState.setY(mxRec.getY());
                clonedState.setWidth(mxRec.getWidth());
                clonedState.setHeight(mxRec.getHeight());
                clonedState.setStyle(sty[i]);
            } else {
                List<mxPoint> list = new ArrayList<mxPoint>();
                mxPoint p1 = new mxPoint(Double.parseDouble(sty[i].get("sourceX").toString()), Double.parseDouble(sty[i].get("sourceY").toString()));
                mxPoint p2 = new mxPoint(Double.parseDouble(sty[i].get("targetX").toString()), Double.parseDouble(sty[i].get("targetY").toString()));
                Point2D destP1 = new Point2D.Double();
                Point2D destP2 = new Point2D.Double();
                transform.transform(new Point2D.Double(p1.getX(), p1.getY()), destP1);
                transform.transform(new Point2D.Double(p2.getX(), p2.getY()), destP2);
                list.add(new mxPoint(destP1.getX() + dx, destP1.getY() + dy)); //add start point
                if (sty[i].containsKey("htPoints")) {
                    String st = sty[i].get("htPoints").toString();
                    String[] pts = st.split("[|]");
                    for (String pt : pts) {
                        String[] xy = pt.split(",");
                        mxPoint p = new mxPoint(Double.parseDouble(xy[0]), Double.parseDouble(xy[1]));
                        Point2D destP = new Point2D.Double();
                        transform.transform(new Point2D.Double(p.getX(), p.getY()), destP);
                        mxPoint fitP = new mxPoint(destP.getX() + dx, destP.getY() + dy);
                        list.add(fitP);
                    }
                    sty[i].remove("htPoints");
                }
                list.add(new mxPoint(destP2.getX() + dx, destP2.getY() + dy));//add end point

                sty[i].remove("sourceX");
                sty[i].remove("sourceY");
                sty[i].remove("targetX");
                sty[i].remove("targetY");
                mxCell edge = new mxCell("");
                edge.setEdge(true);
                clonedState = new mxCellState(state.getView(), edge, sty[i]);
                clonedState.setAbsolutePoints(list);
                //state.getView().updatePoints(clonedState, list, null, null);
            }
            mxIShape shape = canvas.getShape(sty[i]);
            shape.paintShape(canvas, clonedState);
        }
    }
}